home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 March / macformat-022.iso / Shareware City / Developers / src / out-of-phase-102-c / OutOfPhase 1.02 Source / OutOfPhase Folder / SampleObject.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-23  |  51.0 KB  |  1,782 lines  |  [TEXT/KAHL]

  1. /* SampleObject.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Out Of Phase:  Digital Music Synthesis on General Purpose Computers    */
  5. /*    Copyright (C) 1994  Thomas R. Lawrence                                 */
  6. /*                                                                           */
  7. /*    This program is free software; you can redistribute it and/or modify   */
  8. /*    it under the terms of the GNU General Public License as published by   */
  9. /*    the Free Software Foundation; either version 2 of the License, or      */
  10. /*    (at your option) any later version.                                    */
  11. /*                                                                           */
  12. /*    This program is distributed in the hope that it will be useful,        */
  13. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  14. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
  15. /*    GNU General Public License for more details.                           */
  16. /*                                                                           */
  17. /*    You should have received a copy of the GNU General Public License      */
  18. /*    along with this program; if not, write to the Free Software            */
  19. /*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
  20. /*                                                                           */
  21. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24.  
  25. #include "MiscInfo.h"
  26. #include "Audit.h"
  27. #include "Debug.h"
  28. #include "Definitions.h"
  29.  
  30. #include "SampleObject.h"
  31. #include "Memory.h"
  32. #include "DataMunging.h"
  33. #include "SampleList.h"
  34. #include "SampleWindow.h"
  35. #include "SampleStorageActual.h"
  36. #include "BufferedFileInput.h"
  37. #include "BufferedFileOutput.h"
  38.  
  39.  
  40. struct SampleObjectRec
  41.     {
  42.         MyBoolean                                DataModified;
  43.  
  44.         char*                                        Name;
  45.         SampleStorageActualRec*    SampleData;
  46.         char*                                        SampleFormula;
  47.  
  48.         long                                        Origin;
  49.         long                                        LoopStart1;
  50.         long                                        LoopStart2;
  51.         long                                        LoopStart3;
  52.         long                                        LoopEnd1;
  53.         long                                        LoopEnd2;
  54.         long                                        LoopEnd3;
  55.         long                                        SamplingRate;
  56.         double                                    NaturalFrequency;
  57.  
  58.         SampleWindowRec*                SampleWindow;
  59.  
  60.         struct CodeCenterRec*        CodeCenter;
  61.         struct MainWindowRec*        MainWindow;
  62.         SampleListRec*                    SampleList;
  63.  
  64.         short                                        SavedWindowXLoc;
  65.         short                                        SavedWindowYLoc;
  66.         short                                        SavedWindowWidth;
  67.         short                                        SavedWindowHeight;
  68.     };
  69.  
  70.  
  71. /* allocate and create a new empty sample object, with reasonable defaults */
  72. SampleObjectRec*            NewSampleObject(struct CodeCenterRec* CodeCenter,
  73.                                                 struct MainWindowRec* MainWindow,
  74.                                                 SampleListRec* SampleList)
  75.     {
  76.         SampleObjectRec*        SampObj;
  77.  
  78.         SampObj = (SampleObjectRec*)AllocPtrCanFail(sizeof(SampleObjectRec),
  79.             "SampleObjectRec");
  80.         if (SampObj == NIL)
  81.             {
  82.              FailurePoint1:
  83.                 return NIL;
  84.             }
  85.         SampObj->SampleData = NewSampleStorageActual(eSample16bit,eSampleMono,0);
  86.         if (SampObj->SampleData == NIL)
  87.             {
  88.              FailurePoint2:
  89.                 ReleasePtr((char*)SampObj);
  90.                 goto FailurePoint1;
  91.             }
  92.         SampObj->Name = StringToBlockCopy("untitled");
  93.         if (SampObj->Name == NIL)
  94.             {
  95.              FailurePoint3:
  96.                 DisposeSampleStorageActual(SampObj->SampleData);
  97.                 goto FailurePoint2;
  98.             }
  99.         SetTag(SampObj->Name,"SampleName");
  100.         SampObj->SampleFormula = StringToBlockCopy(
  101.             "# This expression applies to the ENTIRE sample.\x0a"
  102.             "# loopstart, loopend, origin, samplingrate, selectstart, selectend : integer\x0a"
  103.             "# naturalfrequency : double; [leftdata, rightdata | data] : fixedarray\x0a");
  104.         if (SampObj->SampleFormula == NIL)
  105.             {
  106.              FailurePoint4:
  107.                 ReleasePtr(SampObj->Name);
  108.                 goto FailurePoint3;
  109.             }
  110.         /* initialize to reasonable values */
  111.         SampObj->DataModified = False;
  112.         SampObj->Origin = 0;
  113.         SampObj->LoopStart1 = 0;
  114.         SampObj->LoopStart2 = 0;
  115.         SampObj->LoopStart3 = 0;
  116.         SampObj->LoopEnd1 = 0;
  117.         SampObj->LoopEnd2 = 0;
  118.         SampObj->LoopEnd3 = 0;
  119.         SampObj->SamplingRate = 22050;
  120.         SampObj->NaturalFrequency = 261.625565300598635;
  121.         SampObj->CodeCenter = CodeCenter;
  122.         SampObj->MainWindow = MainWindow;
  123.         SampObj->SampleList = SampleList;
  124.         SampObj->SampleWindow = NIL;
  125.         SampObj->SavedWindowXLoc = 0;
  126.         SampObj->SavedWindowYLoc = 0;
  127.         SampObj->SavedWindowWidth = 0;
  128.         SampObj->SavedWindowHeight = 0;
  129.         return SampObj;
  130.     }
  131.  
  132.  
  133. /* allocate and create a sample object with the specified attributes */
  134. /* the RawData field must not be NIL.  It will be copied for the new sample */
  135. SampleObjectRec*            NewSampleObjectInitialized(struct CodeCenterRec* CodeCenter,
  136.                                                 struct MainWindowRec* MainWindow,
  137.                                                 struct SampleListRec* SampleList, char* DataToCopy,
  138.                                                 NumBitsType NumBits, NumChannelsType NumChannels, long Origin,
  139.                                                 long LoopStart1, long LoopStart2, long LoopStart3,
  140.                                                 long LoopEnd1, long LoopEnd2, long LoopEnd3, long SamplingRate,
  141.                                                 double NaturalFrequency)
  142.     {
  143.         SampleObjectRec*        SampObj;
  144.         long                                NumSampleFrames;
  145.         long                                Scan;
  146.  
  147.         SampObj = (SampleObjectRec*)AllocPtrCanFail(sizeof(SampleObjectRec),
  148.             "SampleObjectRec");
  149.         if (SampObj == NIL)
  150.             {
  151.              FailurePoint1:
  152.                 return NIL;
  153.             }
  154.         NumSampleFrames = PtrSize(DataToCopy);
  155.         switch (NumBits)
  156.             {
  157.                 default:
  158.                     EXECUTE(PRERR(ForceAbort,"NewSampleObjectInitialized:  bad num bits"));
  159.                     break;
  160.                 case eSample8bit:
  161.                     switch (NumChannels)
  162.                         {
  163.                             default:
  164.                                 EXECUTE(PRERR(ForceAbort,"NewSampleObjectInitialized:  bad num channels"));
  165.                                 break;
  166.                             case eSampleMono:
  167.                                 NumSampleFrames = NumSampleFrames / 1;
  168.                                 break;
  169.                             case eSampleStereo:
  170.                                 NumSampleFrames = NumSampleFrames / 2;
  171.                                 break;
  172.                         }
  173.                     break;
  174.                 case eSample16bit:
  175.                     switch (NumChannels)
  176.                         {
  177.                             default:
  178.                                 EXECUTE(PRERR(ForceAbort,"NewSampleObjectInitialized:  bad num channels"));
  179.                                 break;
  180.                             case eSampleMono:
  181.                                 NumSampleFrames = NumSampleFrames / ((sizeof(short) / sizeof(char)));
  182.                                 break;
  183.                             case eSampleStereo:
  184.                                 NumSampleFrames = NumSampleFrames / (2 * (sizeof(short) / sizeof(char)));
  185.                                 break;
  186.                         }
  187.                     break;
  188.             }
  189.         SampObj->SampleData = NewSampleStorageActual(NumBits,NumChannels,NumSampleFrames);
  190.         if (SampObj->SampleData == NIL)
  191.             {
  192.              FailurePoint2:
  193.                 ReleasePtr((char*)SampObj);
  194.                 goto FailurePoint1;
  195.             }
  196.         for (Scan = 0; Scan < NumSampleFrames; Scan += 1)
  197.             {
  198.                 switch (NumBits)
  199.                     {
  200.                         default:
  201.                             EXECUTE(PRERR(ForceAbort,"NewSampleObjectInitialized:  bad num bits"));
  202.                             break;
  203.                         case eSample8bit:
  204.                             switch (NumChannels)
  205.                                 {
  206.                                     default:
  207.                                         EXECUTE(PRERR(ForceAbort,"NewSampleObjectInitialized:  bad num channels"));
  208.                                         break;
  209.                                     case eSampleMono:
  210.                                         PRNGCHK(DataToCopy,&(((char*)DataToCopy)[Scan]),sizeof(char));
  211.                                         SetSampleStorageActualValue(SampObj->SampleData,Scan,eMonoChannel,
  212.                                             double2largefixed(((double)(((char*)DataToCopy)[Scan]))
  213.                                             / MAX8BIT));
  214.                                         break;
  215.                                     case eSampleStereo:
  216.                                         PRNGCHK(DataToCopy,&(((char*)DataToCopy)[2 * Scan]),
  217.                                             sizeof(char));
  218.                                         SetSampleStorageActualValue(SampObj->SampleData,Scan,eLeftChannel,
  219.                                             double2largefixed(((double)(((char*)DataToCopy)[2 * Scan]))
  220.                                             / MAX8BIT));
  221.                                         PRNGCHK(DataToCopy,&(((char*)DataToCopy)[(2 * Scan) + 1]),
  222.                                             sizeof(char));
  223.                                         SetSampleStorageActualValue(SampObj->SampleData,Scan,eRightChannel,
  224.                                             double2largefixed(((double)(((char*)DataToCopy)[(2 * Scan) + 1]))
  225.                                             / MAX8BIT));
  226.                                         break;
  227.                                 }
  228.                             break;
  229.                         case eSample16bit:
  230.                             switch (NumChannels)
  231.                                 {
  232.                                     default:
  233.                                         EXECUTE(PRERR(ForceAbort,"NewSampleObjectInitialized:  bad num channels"));
  234.                                         break;
  235.                                     case eSampleMono:
  236.                                         PRNGCHK(DataToCopy,&(((short*)DataToCopy)[Scan]),sizeof(short));
  237.                                         SetSampleStorageActualValue(SampObj->SampleData,Scan,eMonoChannel,
  238.                                             double2largefixed(((double)(((short*)DataToCopy)[Scan]))
  239.                                             / MAX16BIT));
  240.                                         break;
  241.                                     case eSampleStereo:
  242.                                         PRNGCHK(DataToCopy,&(((short*)DataToCopy)[2 * Scan]),
  243.                                             sizeof(short));
  244.                                         SetSampleStorageActualValue(SampObj->SampleData,Scan,eLeftChannel,
  245.                                             double2largefixed(((double)(((short*)DataToCopy)[2 * Scan]))
  246.                                             / MAX16BIT));
  247.                                         PRNGCHK(DataToCopy,&(((short*)DataToCopy)[(2 * Scan) + 1]),
  248.                                             sizeof(short));
  249.                                         SetSampleStorageActualValue(SampObj->SampleData,Scan,eRightChannel,
  250.                                             double2largefixed(((double)(((short*)DataToCopy)[(2 * Scan) + 1]))
  251.                                             / MAX16BIT));
  252.                                         break;
  253.                                 }
  254.                             break;
  255.                     }
  256.             }
  257.         SampObj->Name = StringToBlockCopy("Algorithmic Sample Copy");
  258.         if (SampObj->Name == NIL)
  259.             {
  260.              FailurePoint3:
  261.                 DisposeSampleStorageActual(SampObj->SampleData);
  262.                 goto FailurePoint2;
  263.             }
  264.         SetTag(SampObj->Name,"SampleName");
  265.         SampObj->SampleFormula = StringToBlockCopy(
  266.             "# This expression applies to the ENTIRE sample.\x0a"
  267.             "# loopstart, loopend, origin, samplingrate, selectstart, selectend : integer\x0a"
  268.             "# naturalfrequency : double; [leftdata, rightdata | data] : fixedarray\x0a");
  269.         if (SampObj->SampleFormula == NIL)
  270.             {
  271.              FailurePoint4:
  272.                 ReleasePtr(SampObj->Name);
  273.                 goto FailurePoint3;
  274.             }
  275.         /* initialize to reasonable values */
  276.         SampObj->DataModified = True;
  277.         SampObj->CodeCenter = CodeCenter;
  278.         SampObj->MainWindow = MainWindow;
  279.         SampObj->SampleList = SampleList;
  280.         SampObj->SampleWindow = NIL;
  281.         SampleObjectPutOrigin(SampObj,Origin);
  282.         SampleObjectPutLoopStart1(SampObj,LoopStart1);
  283.         SampleObjectPutLoopStart2(SampObj,LoopStart2);
  284.         SampleObjectPutLoopStart3(SampObj,LoopStart3);
  285.         SampleObjectPutLoopEnd1(SampObj,LoopEnd1);
  286.         SampleObjectPutLoopEnd2(SampObj,LoopEnd2);
  287.         SampleObjectPutLoopEnd3(SampObj,LoopEnd3);
  288.         SampleObjectPutSamplingRate(SampObj,SamplingRate);
  289.         SampleObjectPutNaturalFrequency(SampObj,NaturalFrequency);
  290.         SampObj->SavedWindowXLoc = 0;
  291.         SampObj->SavedWindowYLoc = 0;
  292.         SampObj->SavedWindowWidth = 0;
  293.         SampObj->SavedWindowHeight = 0;
  294.         return SampObj;
  295.     }
  296.  
  297.  
  298. /* dispose of a sample object */
  299. void                                    DisposeSampleObject(SampleObjectRec* SampObj)
  300.     {
  301.         CheckPtrExistence(SampObj);
  302.         if (SampObj->SampleWindow != NIL)
  303.             {
  304.                 DisposeSampleWindow(SampObj->SampleWindow);
  305.                 ERROR(SampObj->SampleWindow != NIL,PRERR(AllowResume,
  306.                     "DisposeSampleObject:  window thing not NIL after DisposeSampleWindow"));
  307.             }
  308.         DisposeSampleStorageActual(SampObj->SampleData);
  309.         ReleasePtr(SampObj->Name);
  310.         ReleasePtr(SampObj->SampleFormula);
  311.         ReleasePtr((char*)SampObj);
  312.     }
  313.  
  314.  
  315. /* find out if sample object has been modified */
  316. MyBoolean                            HasSampleObjectBeenModified(SampleObjectRec* SampObj)
  317.     {
  318.         CheckPtrExistence(SampObj);
  319.         if (SampObj->SampleWindow != NIL)
  320.             {
  321.                 return SampObj->DataModified
  322.                     || HasSampleWindowBeenModified(SampObj->SampleWindow);
  323.             }
  324.          else
  325.             {
  326.                 return SampObj->DataModified;
  327.             }
  328.     }
  329.  
  330.  
  331. /* get a copy of the sample's name. */
  332. char*                                    SampleObjectGetNameCopy(SampleObjectRec* SampObj)
  333.     {
  334.         char*                                NameTemp;
  335.  
  336.         CheckPtrExistence(SampObj);
  337.         if (SampObj->SampleWindow != NIL)
  338.             {
  339.                 NameTemp = SampleWindowGetNameCopy(SampObj->SampleWindow);
  340.             }
  341.          else
  342.             {
  343.                 NameTemp = CopyPtr(SampObj->Name);
  344.             }
  345.         if (NameTemp != NIL)
  346.             {
  347.                 SetTag(NameTemp,"SampleNameCopy");
  348.             }
  349.         return NameTemp;
  350.     }
  351.  
  352.  
  353. /* set the sample's name.  the object becomes the owner of the Name block so */
  354. /* the caller should not release it. */
  355. void                                    SampleObjectNewName(SampleObjectRec* SampObj, char* Name)
  356.     {
  357.         CheckPtrExistence(SampObj);
  358.         CheckPtrExistence(Name);
  359.         ReleasePtr(SampObj->Name);
  360.         SetTag(Name,"SampleName");
  361.         SampObj->Name = Name;
  362.         SampObj->DataModified = True;
  363.         if (SampObj->SampleWindow != NIL)
  364.             {
  365.                 SampleWindowObjectNameChange(SampObj->SampleWindow,Name);
  366.             }
  367.         SampleListSampleNameChanged(SampObj->SampleList,SampObj);
  368.     }
  369.  
  370.  
  371. /* get a copy of the formula applied to the sample */
  372. char*                                    SampleObjectGetFormulaCopy(SampleObjectRec* SampObj)
  373.     {
  374.         char*                                TextCopy;
  375.  
  376.         CheckPtrExistence(SampObj);
  377.         if (SampObj->SampleWindow != NIL)
  378.             {
  379.                 TextCopy = SampleWindowGetFormulaCopy(SampObj->SampleWindow);
  380.             }
  381.          else
  382.             {
  383.                 TextCopy = CopyPtr(SampObj->SampleFormula);
  384.             }
  385.         if (TextCopy != NIL)
  386.             {
  387.                 SetTag(TextCopy,"SampFormulaCopy");
  388.             }
  389.         return TextCopy;
  390.     }
  391.  
  392.  
  393. /* install a new formula into the sample.  the object becomes the owner of the */
  394. /* formula, so the caller should not release it */
  395. void                                    SampleObjectNewFormula(SampleObjectRec* SampObj, char* Formula)
  396.     {
  397.         CheckPtrExistence(SampObj);
  398.         CheckPtrExistence(Formula);
  399.         ReleasePtr(SampObj->SampleFormula);
  400.         SetTag(Formula,"SampleFormula");
  401.         SampObj->SampleFormula = Formula;
  402.         SampObj->DataModified = True;
  403.     }
  404.  
  405.  
  406. /* get the number of bits in a channel for the sample */
  407. NumBitsType                        SampleObjectGetNumBits(SampleObjectRec* SampObj)
  408.     {
  409.         CheckPtrExistence(SampObj);
  410.         if (SampObj->SampleWindow != NIL)
  411.             {
  412.                 return SampleWindowGetNumBits(SampObj->SampleWindow);
  413.             }
  414.          else
  415.             {
  416.                 return GetSampleStorageActualNumBits(SampObj->SampleData);
  417.             }
  418.     }
  419.  
  420.  
  421. /* get the number of channels in the sample */
  422. NumChannelsType                SampleObjectGetNumChannels(SampleObjectRec* SampObj)
  423.     {
  424.         CheckPtrExistence(SampObj);
  425.         if (SampObj->SampleWindow != NIL)
  426.             {
  427.                 return SampleWindowGetNumChannels(SampObj->SampleWindow);
  428.             }
  429.          else
  430.             {
  431.                 return GetSampleStorageActualNumChannels(SampObj->SampleData);
  432.             }
  433.     }
  434.  
  435.  
  436. long                                    SampleObjectGetOrigin(SampleObjectRec* SampObj)
  437.     {
  438.         CheckPtrExistence(SampObj);
  439.         if (SampObj->SampleWindow != NIL)
  440.             {
  441.                 return SampleWindowGetOrigin(SampObj->SampleWindow);
  442.             }
  443.          else
  444.             {
  445.                 return SampObj->Origin;
  446.             }
  447.     }
  448.  
  449.  
  450. long                                    SampleObjectGetLoopStart1(SampleObjectRec* SampObj)
  451.     {
  452.         CheckPtrExistence(SampObj);
  453.         if ((SampObj->SampleWindow != NIL)
  454.             && (eSampleLoop1 == SampleWindowEditingWhichLoop(SampObj->SampleWindow)))
  455.             {
  456.                 return SampleWindowGetLoopStart(SampObj->SampleWindow);
  457.             }
  458.          else
  459.             {
  460.                 return SampObj->LoopStart1;
  461.             }
  462.     }
  463.  
  464.  
  465. long                                    SampleObjectGetLoopStart2(SampleObjectRec* SampObj)
  466.     {
  467.         CheckPtrExistence(SampObj);
  468.         if ((SampObj->SampleWindow != NIL)
  469.             && (eSampleLoop2 == SampleWindowEditingWhichLoop(SampObj->SampleWindow)))
  470.             {
  471.                 return SampleWindowGetLoopStart(SampObj->SampleWindow);
  472.             }
  473.          else
  474.             {
  475.                 return SampObj->LoopStart2;
  476.             }
  477.     }
  478.  
  479.  
  480. long                                    SampleObjectGetLoopStart3(SampleObjectRec* SampObj)
  481.     {
  482.         CheckPtrExistence(SampObj);
  483.         if ((SampObj->SampleWindow != NIL)
  484.             && (eSampleLoop3 == SampleWindowEditingWhichLoop(SampObj->SampleWindow)))
  485.             {
  486.                 return SampleWindowGetLoopStart(SampObj->SampleWindow);
  487.             }
  488.          else
  489.             {
  490.                 return SampObj->LoopStart3;
  491.             }
  492.     }
  493.  
  494.  
  495. long                                    SampleObjectGetLoopEnd1(SampleObjectRec* SampObj)
  496.     {
  497.         CheckPtrExistence(SampObj);
  498.         if ((SampObj->SampleWindow != NIL)
  499.             && (eSampleLoop1 == SampleWindowEditingWhichLoop(SampObj->SampleWindow)))
  500.             {
  501.                 return SampleWindowGetLoopEnd(SampObj->SampleWindow);
  502.             }
  503.          else
  504.             {
  505.                 return SampObj->LoopEnd1;
  506.             }
  507.     }
  508.  
  509.  
  510. long                                    SampleObjectGetLoopEnd2(SampleObjectRec* SampObj)
  511.     {
  512.         CheckPtrExistence(SampObj);
  513.         if ((SampObj->SampleWindow != NIL)
  514.             && (eSampleLoop2 == SampleWindowEditingWhichLoop(SampObj->SampleWindow)))
  515.             {
  516.                 return SampleWindowGetLoopEnd(SampObj->SampleWindow);
  517.             }
  518.          else
  519.             {
  520.                 return SampObj->LoopEnd2;
  521.             }
  522.     }
  523.  
  524.  
  525. long                                    SampleObjectGetLoopEnd3(SampleObjectRec* SampObj)
  526.     {
  527.         CheckPtrExistence(SampObj);
  528.         if ((SampObj->SampleWindow != NIL)
  529.             && (eSampleLoop3 == SampleWindowEditingWhichLoop(SampObj->SampleWindow)))
  530.             {
  531.                 return SampleWindowGetLoopEnd(SampObj->SampleWindow);
  532.             }
  533.          else
  534.             {
  535.                 return SampObj->LoopEnd3;
  536.             }
  537.     }
  538.  
  539.  
  540. long                                    SampleObjectGetSamplingRate(SampleObjectRec* SampObj)
  541.     {
  542.         CheckPtrExistence(SampObj);
  543.         if (SampObj->SampleWindow != NIL)
  544.             {
  545.                 return SampleWindowGetSamplingRate(SampObj->SampleWindow);
  546.             }
  547.          else
  548.             {
  549.                 return SampObj->SamplingRate;
  550.             }
  551.     }
  552.  
  553.  
  554. double                                SampleObjectGetNaturalFrequency(SampleObjectRec* SampObj)
  555.     {
  556.         CheckPtrExistence(SampObj);
  557.         if (SampObj->SampleWindow != NIL)
  558.             {
  559.                 return SampleWindowGetNaturalFrequency(SampObj->SampleWindow);
  560.             }
  561.          else
  562.             {
  563.                 return SampObj->NaturalFrequency;
  564.             }
  565.     }
  566.  
  567.  
  568. /* get the number of sample frames */
  569. long                                    SampleObjectGetNumSampleFrames(SampleObjectRec* SampObj)
  570.     {
  571.         CheckPtrExistence(SampObj);
  572.         if (SampObj->SampleWindow != NIL)
  573.             {
  574.                 return SampleWindowGetNumFrames(SampObj->SampleWindow);
  575.             }
  576.          else
  577.             {
  578.                 return GetSampleStorageActualNumFrames(SampObj->SampleData);
  579.             }
  580.     }
  581.  
  582.  
  583. /* get a pointer to the raw data for the sample.  this pointer is the */
  584. /* actual data, not a copy, so don't dispose of it.  if any operations are performed */
  585. /* on the sample, this pointer may become invalid.  format of raw data: */
  586. /*  - mono, 8-bit:  array of signed bytes */
  587. /*  - stereo, 8-bit:  array of signed bytes, grouped in pairs.  the one lower in */
  588. /*    memory is the left channel */
  589. /*  - mono, 16-bit:  array of signed short integers (either 2 or 4 bytes) */
  590. /*  - stereo, 16-bit:  array of signed short integers, grouped in pairs.  the one */
  591. /*    lower in memory is the left channel */
  592. char*                                    SampleObjectGetRawData(SampleObjectRec* SampObj)
  593.     {
  594.         CheckPtrExistence(SampObj);
  595.         if (SampObj->SampleWindow != NIL)
  596.             {
  597.                 if (!SampleWindowForceUpdateSampleObjectData(SampObj->SampleWindow))
  598.                     {
  599.                         return NIL;
  600.                     }
  601.             }
  602.         return GetSampleStorageActualRawData(SampObj->SampleData);
  603.     }
  604.  
  605.  
  606. /* put new data into the sample.  the num channels, bits, and data has to be put */
  607. /* in all at the same time so that no reformatting routines need to be supplied. */
  608. /* the object becomes owner of the data block, so it must not be released by the */
  609. /* caller.  this call should also be made BEFORE any of the calls to set the */
  610. /* attributes, since the attribute's values will be constrained based on this data */
  611. void                                    SampleObjectPutNewSample(SampleObjectRec* SampObj,
  612.                                                 SampleStorageActualRec* NewStorage)
  613.     {
  614.         long                                NumFrames;
  615.  
  616.         CheckPtrExistence(SampObj);
  617.         CheckPtrExistence(NewStorage);
  618.         DisposeSampleStorageActual(SampObj->SampleData);
  619.         SampObj->SampleData = NewStorage;
  620.         NumFrames = GetSampleStorageActualNumFrames(NewStorage);
  621.         if (SampObj->LoopStart1 > NumFrames)
  622.             {
  623.                 SampObj->LoopStart1 = NumFrames;
  624.             }
  625.         if (SampObj->LoopStart2 > NumFrames)
  626.             {
  627.                 SampObj->LoopStart2 = NumFrames;
  628.             }
  629.         if (SampObj->LoopStart3 > NumFrames)
  630.             {
  631.                 SampObj->LoopStart3 = NumFrames;
  632.             }
  633.         if (SampObj->LoopEnd1 > NumFrames)
  634.             {
  635.                 SampObj->LoopEnd1 = NumFrames;
  636.             }
  637.         if (SampObj->LoopEnd2 > NumFrames)
  638.             {
  639.                 SampObj->LoopEnd2 = NumFrames;
  640.             }
  641.         if (SampObj->LoopEnd3 > NumFrames)
  642.             {
  643.                 SampObj->LoopEnd3 = NumFrames;
  644.             }
  645.         SampObj->DataModified = True;
  646.     }
  647.  
  648.  
  649. void                                    SampleObjectPutOrigin(SampleObjectRec* SampObj, long Origin)
  650.     {
  651.         CheckPtrExistence(SampObj);
  652.         SampObj->Origin = Origin;
  653.         SampObj->DataModified = True;
  654.     }
  655.  
  656.  
  657. void                                    SampleObjectPutLoopStart1(SampleObjectRec* SampObj, long LoopStart)
  658.     {
  659.         long                                NumFrames;
  660.  
  661.         CheckPtrExistence(SampObj);
  662.         if (SampObj->SampleWindow != NIL)
  663.             {
  664.                 NumFrames = SampleWindowGetNumFrames(SampObj->SampleWindow);
  665.             }
  666.          else
  667.             {
  668.                 NumFrames = GetSampleStorageActualNumFrames(SampObj->SampleData);
  669.             }
  670.         if (LoopStart < 0)
  671.             {
  672.                 LoopStart = 0;
  673.             }
  674.         if (LoopStart > NumFrames)
  675.             {
  676.                 LoopStart = NumFrames;
  677.             }
  678.         SampObj->LoopStart1 = LoopStart;
  679.         if (LoopStart > SampObj->LoopEnd1)
  680.             {
  681.                 SampObj->LoopEnd1 = LoopStart;
  682.             }
  683.         SampObj->DataModified = True;
  684.     }
  685.  
  686.  
  687. void                                    SampleObjectPutLoopStart2(SampleObjectRec* SampObj, long LoopStart)
  688.     {
  689.         long                                NumFrames;
  690.  
  691.         CheckPtrExistence(SampObj);
  692.         if (SampObj->SampleWindow != NIL)
  693.             {
  694.                 NumFrames = SampleWindowGetNumFrames(SampObj->SampleWindow);
  695.             }
  696.          else
  697.             {
  698.                 NumFrames = GetSampleStorageActualNumFrames(SampObj->SampleData);
  699.             }
  700.         if (LoopStart < 0)
  701.             {
  702.                 LoopStart = 0;
  703.             }
  704.         if (LoopStart > NumFrames)
  705.             {
  706.                 LoopStart = NumFrames;
  707.             }
  708.         SampObj->LoopStart2 = LoopStart;
  709.         if (LoopStart > SampObj->LoopEnd1)
  710.             {
  711.                 SampObj->LoopEnd2 = LoopStart;
  712.             }
  713.         SampObj->DataModified = True;
  714.     }
  715.  
  716.  
  717. void                                    SampleObjectPutLoopStart3(SampleObjectRec* SampObj, long LoopStart)
  718.     {
  719.         long                                NumFrames;
  720.  
  721.         CheckPtrExistence(SampObj);
  722.         if (SampObj->SampleWindow != NIL)
  723.             {
  724.                 NumFrames = SampleWindowGetNumFrames(SampObj->SampleWindow);
  725.             }
  726.          else
  727.             {
  728.                 NumFrames = GetSampleStorageActualNumFrames(SampObj->SampleData);
  729.             }
  730.         if (LoopStart < 0)
  731.             {
  732.                 LoopStart = 0;
  733.             }
  734.         if (LoopStart > NumFrames)
  735.             {
  736.                 LoopStart = NumFrames;
  737.             }
  738.         SampObj->LoopStart3 = LoopStart;
  739.         if (LoopStart > SampObj->LoopEnd1)
  740.             {
  741.                 SampObj->LoopEnd3 = LoopStart;
  742.             }
  743.         SampObj->DataModified = True;
  744.     }
  745.  
  746.  
  747. void                                    SampleObjectPutLoopEnd1(SampleObjectRec* SampObj, long LoopEnd)
  748.     {
  749.         long                                NumFrames;
  750.  
  751.         CheckPtrExistence(SampObj);
  752.         if (SampObj->SampleWindow != NIL)
  753.             {
  754.                 NumFrames = SampleWindowGetNumFrames(SampObj->SampleWindow);
  755.             }
  756.          else
  757.             {
  758.                 NumFrames = GetSampleStorageActualNumFrames(SampObj->SampleData);
  759.             }
  760.         if (LoopEnd < 0)
  761.             {
  762.                 LoopEnd = 0;
  763.             }
  764.         if (LoopEnd > NumFrames)
  765.             {
  766.                 LoopEnd = NumFrames;
  767.             }
  768.         if (LoopEnd < SampObj->LoopStart1)
  769.             {
  770.                 LoopEnd = SampObj->LoopStart1;
  771.             }
  772.         SampObj->LoopEnd1 = LoopEnd;
  773.         SampObj->DataModified = True;
  774.     }
  775.  
  776.  
  777. void                                    SampleObjectPutLoopEnd2(SampleObjectRec* SampObj, long LoopEnd)
  778.     {
  779.         long                                NumFrames;
  780.  
  781.         CheckPtrExistence(SampObj);
  782.         if (SampObj->SampleWindow != NIL)
  783.             {
  784.                 NumFrames = SampleWindowGetNumFrames(SampObj->SampleWindow);
  785.             }
  786.          else
  787.             {
  788.                 NumFrames = GetSampleStorageActualNumFrames(SampObj->SampleData);
  789.             }
  790.         if (LoopEnd < 0)
  791.             {
  792.                 LoopEnd = 0;
  793.             }
  794.         if (LoopEnd > NumFrames)
  795.             {
  796.                 LoopEnd = NumFrames;
  797.             }
  798.         if (LoopEnd < SampObj->LoopStart2)
  799.             {
  800.                 LoopEnd = SampObj->LoopStart2;
  801.             }
  802.         SampObj->LoopEnd2 = LoopEnd;
  803.         SampObj->DataModified = True;
  804.     }
  805.  
  806.  
  807. void                                    SampleObjectPutLoopEnd3(SampleObjectRec* SampObj, long LoopEnd)
  808.     {
  809.         long                                NumFrames;
  810.  
  811.         CheckPtrExistence(SampObj);
  812.         if (SampObj->SampleWindow != NIL)
  813.             {
  814.                 NumFrames = SampleWindowGetNumFrames(SampObj->SampleWindow);
  815.             }
  816.          else
  817.             {
  818.                 NumFrames = GetSampleStorageActualNumFrames(SampObj->SampleData);
  819.             }
  820.         if (LoopEnd < 0)
  821.             {
  822.                 LoopEnd = 0;
  823.             }
  824.         if (LoopEnd > NumFrames)
  825.             {
  826.                 LoopEnd = NumFrames;
  827.             }
  828.         if (LoopEnd < SampObj->LoopStart3)
  829.             {
  830.                 LoopEnd = SampObj->LoopStart3;
  831.             }
  832.         SampObj->LoopEnd3 = LoopEnd;
  833.         SampObj->DataModified = True;
  834.     }
  835.  
  836.  
  837. void                                    SampleObjectPutSamplingRate(SampleObjectRec* SampObj,
  838.                                                 long SamplingRate)
  839.     {
  840.         CheckPtrExistence(SampObj);
  841.         if (SamplingRate < MINSAMPLINGRATE)
  842.             {
  843.                 SamplingRate = MINSAMPLINGRATE;
  844.             }
  845.         if (SamplingRate > MAXSAMPLINGRATE)
  846.             {
  847.                 SamplingRate = MAXSAMPLINGRATE;
  848.             }
  849.         SampObj->SamplingRate = SamplingRate;
  850.         SampObj->DataModified = True;
  851.     }
  852.  
  853.  
  854. void                                    SampleObjectPutNaturalFrequency(SampleObjectRec* SampObj,
  855.                                                 double NaturalFrequency)
  856.     {
  857.         CheckPtrExistence(SampObj);
  858.         if (NaturalFrequency < MINNATURALFREQ)
  859.             {
  860.                 NaturalFrequency = MINNATURALFREQ;
  861.             }
  862.         if (NaturalFrequency > MAXNATURALFREQ)
  863.             {
  864.                 NaturalFrequency = MAXNATURALFREQ;
  865.             }
  866.         SampObj->NaturalFrequency = NaturalFrequency;
  867.         SampObj->DataModified = True;
  868.     }
  869.  
  870.  
  871. /* call which makes object open its editor window */
  872. MyBoolean                            SampleObjectOpenWindow(SampleObjectRec* SampObj)
  873.     {
  874.         CheckPtrExistence(SampObj);
  875.         if (SampObj->SampleWindow == NIL)
  876.             {
  877.                 SampObj->SampleWindow = NewSampleWindow(SampObj->MainWindow,
  878.                     SampObj,SampObj->CodeCenter,SampObj->SampleData,SampObj->SampleList,
  879.                     SampObj->SavedWindowXLoc,SampObj->SavedWindowYLoc,SampObj->SavedWindowWidth,
  880.                     SampObj->SavedWindowHeight);
  881.             }
  882.          else
  883.             {
  884.                 SampleWindowBringToTop(SampObj->SampleWindow);
  885.             }
  886.         return (SampObj->SampleWindow != NIL);
  887.     }
  888.  
  889.  
  890. /* this is called by the window when it is closing to notify the object. */
  891. /* the object should not take any action. */
  892. void                                    SampleObjectClosingWindowNotify(SampleObjectRec* SampObj,
  893.                                                 short NewXSize, short NewYSize, short NewWidth, short NewHeight)
  894.     {
  895.         CheckPtrExistence(SampObj);
  896.         ERROR(SampObj->SampleWindow == NIL,PRERR(ForceAbort,
  897.             "SampleObjectClosingWindowNotify:  window not open"));
  898.         SampObj->SampleWindow = NIL;
  899.         SampObj->SavedWindowXLoc = NewXSize;
  900.         SampObj->SavedWindowYLoc = NewYSize;
  901.         SampObj->SavedWindowWidth = NewWidth;
  902.         SampObj->SavedWindowHeight = NewHeight;
  903.     }
  904.  
  905.  
  906. largefixedsigned*            SampleObjectGetLeftFixed(SampleObjectRec* SampObj)
  907.     {
  908.         CheckPtrExistence(SampObj);
  909.         ERROR(eSampleStereo != SampleObjectGetNumChannels(SampObj),PRERR(ForceAbort,
  910.             "SampleObjectGetLeftFixed called on mono sample"));
  911.         if (SampObj->SampleWindow != NIL)
  912.             {
  913.                 return SampleWindowGetFixedArrayLeft(SampObj->SampleWindow);
  914.             }
  915.          else
  916.             {
  917.                 return SampleStorageActualGetChannelFixed(SampObj->SampleData,eLeftChannel);
  918.             }
  919.     }
  920.  
  921.  
  922. largefixedsigned*            SampleObjectGetRightFixed(SampleObjectRec* SampObj)
  923.     {
  924.         CheckPtrExistence(SampObj);
  925.         ERROR(eSampleStereo != SampleObjectGetNumChannels(SampObj),PRERR(ForceAbort,
  926.             "SampleObjectGetRightFixed called on mono sample"));
  927.         if (SampObj->SampleWindow != NIL)
  928.             {
  929.                 return SampleWindowGetFixedArrayRight(SampObj->SampleWindow);
  930.             }
  931.          else
  932.             {
  933.                 return SampleStorageActualGetChannelFixed(SampObj->SampleData,eRightChannel);
  934.             }
  935.     }
  936.  
  937.  
  938. largefixedsigned*            SampleObjectGetMonoFixed(SampleObjectRec* SampObj)
  939.     {
  940.         CheckPtrExistence(SampObj);
  941.         ERROR(eSampleMono != SampleObjectGetNumChannels(SampObj),PRERR(ForceAbort,
  942.             "SampleObjectGetMonoFixed called on mono sample"));
  943.         if (SampObj->SampleWindow != NIL)
  944.             {
  945.                 return SampleWindowGetFixedArrayMono(SampObj->SampleWindow);
  946.             }
  947.          else
  948.             {
  949.                 return SampleStorageActualGetChannelFixed(SampObj->SampleData,eMonoChannel);
  950.             }
  951.     }
  952.  
  953.  
  954. /* the document's name has changed, so the window needs to be updated */
  955. void                                    SampleObjectGlobalNameChange(SampleObjectRec* SampObj,
  956.                                                 char* NewFilename)
  957.     {
  958.         CheckPtrExistence(SampObj);
  959.         if (SampObj->SampleWindow != NIL)
  960.             {
  961.                 SampleWindowGlobalNameChange(SampObj->SampleWindow,NewFilename);
  962.             }
  963.     }
  964.  
  965.  
  966. /* Sample Object Subblock Structure: */
  967. /*   1-byte sample version number */
  968. /*       should be 1 */
  969. /*   2-byte little endian window X position (signed, origin at top-left corner) */
  970. /*   2-byte little endian window Y position */
  971. /*   2-byte little endian window width */
  972. /*   2-byte little endian window height */
  973. /*   4-byte little endian sample name length descriptor (positive 2's complement) */
  974. /*   n-byte sample name text (line feed = 0x0a) */
  975. /*   4-byte little endian sample formula length descriptor (positive 2's complement) */
  976. /*   n-byte sample formula text (line feed = 0x0a) */
  977. /*   4-byte little endian sample frame index of sample's origin */
  978. /*   4-byte little endian sample frame index of loop 1 start */
  979. /*       must be a valid index, i.e. >= 0 and < num sample frames */
  980. /*   4-byte little endian sample frame index of loop 1 end */
  981. /*       must be a valid index, i.e. >= 0 and < num sample frames */
  982. /*       also, loop end must not be less than loop start */
  983. /*   4-byte little endian sample frame index of loop 2 start */
  984. /*       must be a valid index, i.e. >= 0 and < num sample frames */
  985. /*   4-byte little endian sample frame index of loop 2 end */
  986. /*       must be a valid index, i.e. >= 0 and < num sample frames */
  987. /*       also, loop end must not be less than loop start */
  988. /*   4-byte little endian sample frame index of loop 3 start */
  989. /*       must be a valid index, i.e. >= 0 and < num sample frames */
  990. /*   4-byte little endian sample frame index of loop 3 end */
  991. /*       must be a valid index, i.e. >= 0 and < num sample frames */
  992. /*       also, loop end must not be less than loop start */
  993. /*   4-byte little endian sampling rate value */
  994. /*       should be between 100 and 65535 */
  995. /*   4-byte little endian natural frequency fractional portion */
  996. /*       unsigned; divide by 2^32 to get the actual fraction */
  997. /*   4-byte little endian natural frequency integer portion */
  998. /*       total natural frequency should be between 0.01 and 1e6 */
  999. /*   4-byte total number of sample frames */
  1000. /*   1-byte mono/stereo flag */
  1001. /*       1 = mono */
  1002. /*       2 = stereo */
  1003. /*   1-byte number of bits per sample point */
  1004. /*       should be 8 or 16 */
  1005. /*   n-bytes of data for sample frames */
  1006. /*       stereo samples have the left channel sample point preceding the right */
  1007. /*       channel sample point. */
  1008. /*       sample points that require more than 1 byte are stored little endian */
  1009. /*       all sample data is stored in signed 2's complement form */
  1010.  
  1011.  
  1012. /* read a sample object from the file */
  1013. FileLoadingErrors            SampleObjectNewFromFile(SampleObjectRec** ObjectOut,
  1014.                                                 struct BufferedInputRec* Input, struct CodeCenterRec* CodeCenter,
  1015.                                                 struct MainWindowRec* MainWindow,
  1016.                                                 struct SampleListRec* SampleList)
  1017.     {
  1018.         unsigned char                UnsignedChar;
  1019.         signed short                SignedShort;
  1020.         signed long                    SignedLong;
  1021.         unsigned long                UnsignedLong;
  1022.         SampleObjectRec*        SampleObject;
  1023.         FileLoadingErrors        Error;
  1024.         NumBitsType                    NumBits;
  1025.         NumChannelsType            NumChannels;
  1026.         long                                NumSampleFrames;
  1027.         long                                Scan;
  1028.  
  1029.         CheckPtrExistence(Input);
  1030.         CheckPtrExistence(CodeCenter);
  1031.         CheckPtrExistence(MainWindow);
  1032.         CheckPtrExistence(SampleList);
  1033.  
  1034.         /* create a sample object */
  1035.         SampleObject = (SampleObjectRec*)AllocPtrCanFail(sizeof(SampleObjectRec),
  1036.             "SampleObjectRec");
  1037.         if (SampleObject == NIL)
  1038.             {
  1039.                 Error = eFileLoadOutOfMemory;
  1040.              FailurePoint1:
  1041.                 return Error;
  1042.             }
  1043.  
  1044.         /*   1-byte sample version number */
  1045.         /*       should be 1 */
  1046.         if (!ReadBufferedUnsignedChar(Input,&UnsignedChar))
  1047.             {
  1048.                 Error = eFileLoadDiskError;
  1049.              FailurePoint2:
  1050.                 ReleasePtr((char*)SampleObject);
  1051.                 goto FailurePoint1;
  1052.             }
  1053.         if (UnsignedChar != 1)
  1054.             {
  1055.                 Error = eFileLoadBadFormat;
  1056.              FailurePoint3:
  1057.                 goto FailurePoint2;
  1058.             }
  1059.  
  1060.         /*   2-byte little endian window X position (signed, origin at top-left corner) */
  1061.         if (!ReadBufferedSignedShortLittleEndian(Input,&SignedShort))
  1062.             {
  1063.                 Error = eFileLoadDiskError;
  1064.              FailurePoint4:
  1065.                 goto FailurePoint3;
  1066.             }
  1067.         SampleObject->SavedWindowXLoc = SignedShort;
  1068.  
  1069.         /*   2-byte little endian window Y position */
  1070.         if (!ReadBufferedSignedShortLittleEndian(Input,&SignedShort))
  1071.             {
  1072.                 Error = eFileLoadDiskError;
  1073.              FailurePoint5:
  1074.                 goto FailurePoint4;
  1075.             }
  1076.         SampleObject->SavedWindowYLoc = SignedShort;
  1077.  
  1078.         /*   2-byte little endian window width */
  1079.         if (!ReadBufferedSignedShortLittleEndian(Input,&SignedShort))
  1080.             {
  1081.                 Error = eFileLoadDiskError;
  1082.              FailurePoint6:
  1083.                 goto FailurePoint5;
  1084.             }
  1085.         SampleObject->SavedWindowWidth = SignedShort;
  1086.  
  1087.         /*   2-byte little endian window height */
  1088.         if (!ReadBufferedSignedShortLittleEndian(Input,&SignedShort))
  1089.             {
  1090.                 Error = eFileLoadDiskError;
  1091.              FailurePoint7:
  1092.                 goto FailurePoint6;
  1093.             }
  1094.         SampleObject->SavedWindowHeight = SignedShort;
  1095.  
  1096.         /*   4-byte little endian sample name length descriptor (positive 2's complement) */
  1097.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1098.             {
  1099.                 Error = eFileLoadDiskError;
  1100.              FailurePoint8:
  1101.                 goto FailurePoint7;
  1102.             }
  1103.         if (SignedLong < 0)
  1104.             {
  1105.                 Error = eFileLoadBadFormat;
  1106.              FailurePoint9:
  1107.                 goto FailurePoint8;
  1108.             }
  1109.  
  1110.         /*   n-byte sample name text (line feed = 0x0a) */
  1111.         SampleObject->Name = AllocPtrCanFail(SignedLong,"SampleObjectRec:  name");
  1112.         if (SampleObject->Name == NIL)
  1113.             {
  1114.                 Error = eFileLoadOutOfMemory;
  1115.              FailurePoint10:
  1116.                 goto FailurePoint9;
  1117.             }
  1118.         if (!ReadBufferedInput(Input,SignedLong,SampleObject->Name))
  1119.             {
  1120.                 Error = eFileLoadDiskError;
  1121.              FailurePoint11:
  1122.                 goto FailurePoint10;
  1123.             }
  1124.  
  1125.         /*   4-byte little endian sample formula length descriptor (positive 2's complement) */
  1126.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1127.             {
  1128.                 Error = eFileLoadDiskError;
  1129.              FailurePoint12:
  1130.                 ReleasePtr(SampleObject->Name);
  1131.                 goto FailurePoint11;
  1132.             }
  1133.         if (SignedLong < 0)
  1134.             {
  1135.                 Error = eFileLoadBadFormat;
  1136.              FailurePoint13:
  1137.                 goto FailurePoint12;
  1138.             }
  1139.  
  1140.         /*   n-byte sample formula text (line feed = 0x0a) */
  1141.         SampleObject->SampleFormula = AllocPtrCanFail(SignedLong,"SampleObjectRec: formula");
  1142.         if (SampleObject->SampleFormula == NIL)
  1143.             {
  1144.                 Error = eFileLoadOutOfMemory;
  1145.              FailurePoint14:
  1146.                 goto FailurePoint13;
  1147.             }
  1148.         if (!ReadBufferedInput(Input,SignedLong,SampleObject->SampleFormula))
  1149.             {
  1150.                 Error = eFileLoadDiskError;
  1151.              FailurePoint15:
  1152.                 ReleasePtr(SampleObject->SampleFormula);
  1153.                 goto FailurePoint14;
  1154.             }
  1155.  
  1156.         /*   4-byte little endian sample frame index of sample's origin */
  1157.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1158.             {
  1159.                 Error = eFileLoadDiskError;
  1160.              FailurePoint16:
  1161.                 goto FailurePoint15;
  1162.             }
  1163.         SampleObject->Origin = SignedLong;
  1164.  
  1165.         /*   4-byte little endian sample frame index of loop 1 start */
  1166.         /*       must be a valid index, i.e. >= 0 and < num sample frames */
  1167.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1168.             {
  1169.                 Error = eFileLoadDiskError;
  1170.              FailurePoint17:
  1171.                 goto FailurePoint16;
  1172.             }
  1173.         SampleObject->LoopStart1 = SignedLong;
  1174.  
  1175.         /*   4-byte little endian sample frame index of loop 1 end */
  1176.         /*       must be a valid index, i.e. >= 0 and < num sample frames */
  1177.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1178.             {
  1179.                 Error = eFileLoadDiskError;
  1180.              FailurePoint18:
  1181.                 goto FailurePoint17;
  1182.             }
  1183.         SampleObject->LoopEnd1 = SignedLong;
  1184.  
  1185.         /*   4-byte little endian sample frame index of loop 2 start */
  1186.         /*       must be a valid index, i.e. >= 0 and < num sample frames */
  1187.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1188.             {
  1189.                 Error = eFileLoadDiskError;
  1190.              FailurePoint19:
  1191.                 goto FailurePoint18;
  1192.             }
  1193.         SampleObject->LoopStart2 = SignedLong;
  1194.  
  1195.         /*   4-byte little endian sample frame index of loop 2 end */
  1196.         /*       must be a valid index, i.e. >= 0 and < num sample frames */
  1197.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1198.             {
  1199.                 Error = eFileLoadDiskError;
  1200.              FailurePoint20:
  1201.                 goto FailurePoint19;
  1202.             }
  1203.         SampleObject->LoopEnd2 = SignedLong;
  1204.  
  1205.         /*   4-byte little endian sample frame index of loop 3 start */
  1206.         /*       must be a valid index, i.e. >= 0 and < num sample frames */
  1207.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1208.             {
  1209.                 Error = eFileLoadDiskError;
  1210.              FailurePoint21:
  1211.                 goto FailurePoint20;
  1212.             }
  1213.         SampleObject->LoopStart3 = SignedLong;
  1214.  
  1215.         /*   4-byte little endian sample frame index of loop 3 end */
  1216.         /*       must be a valid index, i.e. >= 0 and < num sample frames */
  1217.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1218.             {
  1219.                 Error = eFileLoadDiskError;
  1220.              FailurePoint22:
  1221.                 goto FailurePoint21;
  1222.             }
  1223.         SampleObject->LoopEnd3 = SignedLong;
  1224.  
  1225.         /*   4-byte little endian sampling rate value */
  1226.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1227.             {
  1228.                 Error = eFileLoadDiskError;
  1229.              FailurePoint23:
  1230.                 goto FailurePoint22;
  1231.             }
  1232.         if (SignedLong < MINSAMPLINGRATE)
  1233.             {
  1234.                 SignedLong = MINSAMPLINGRATE;
  1235.             }
  1236.         if (SignedLong > MAXSAMPLINGRATE)
  1237.             {
  1238.                 SignedLong = MAXSAMPLINGRATE;
  1239.             }
  1240.         SampleObject->SamplingRate = SignedLong;
  1241.  
  1242.         /*   4-byte little endian natural frequency fractional portion */
  1243.         /*       unsigned; divide by 2^32 to get the actual fraction */
  1244.         if (!ReadBufferedUnsignedLongLittleEndian(Input,&UnsignedLong))
  1245.             {
  1246.                 Error = eFileLoadDiskError;
  1247.              FailurePoint24:
  1248.                 goto FailurePoint23;
  1249.             }
  1250.         SampleObject->NaturalFrequency = UnsignedLong / 4294967296.0L;
  1251.  
  1252.         /*   4-byte little endian natural frequency integer portion */
  1253.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1254.             {
  1255.                 Error = eFileLoadDiskError;
  1256.              FailurePoint25:
  1257.                 goto FailurePoint24;
  1258.             }
  1259.         SampleObject->NaturalFrequency += SignedLong;
  1260.         if (SampleObject->NaturalFrequency < MINNATURALFREQ)
  1261.             {
  1262.                 SampleObject->NaturalFrequency = MINNATURALFREQ;
  1263.             }
  1264.         if (SampleObject->NaturalFrequency > MAXNATURALFREQ)
  1265.             {
  1266.                 SampleObject->NaturalFrequency = MAXNATURALFREQ;
  1267.             }
  1268.  
  1269.         /*   4-byte total number of sample frames */
  1270.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1271.             {
  1272.                 Error = eFileLoadDiskError;
  1273.              FailurePoint26:
  1274.                 goto FailurePoint25;
  1275.             }
  1276.         if (SignedLong < 0)
  1277.             {
  1278.                 Error = eFileLoadBadFormat;
  1279.              FailurePoint27:
  1280.                 goto FailurePoint26;
  1281.             }
  1282.         NumSampleFrames = SignedLong;
  1283.         /* now, check the loop start and end points to make sure they are within range */
  1284.         if ((SampleObject->LoopStart1 < 0) || (SampleObject->LoopStart1 > SignedLong)
  1285.             || (SampleObject->LoopStart1 > SampleObject->LoopEnd1)
  1286.             || (SampleObject->LoopStart2 < 0) || (SampleObject->LoopStart2 > SignedLong)
  1287.             || (SampleObject->LoopStart2 > SampleObject->LoopEnd2)
  1288.             || (SampleObject->LoopStart3 < 0) || (SampleObject->LoopStart3 > SignedLong)
  1289.             || (SampleObject->LoopStart3 > SampleObject->LoopEnd3))
  1290.             {
  1291.                 Error = eFileLoadBadFormat;
  1292.              FailurePoint28:
  1293.                 goto FailurePoint27;
  1294.             }
  1295.  
  1296.         /*   1-byte mono/stereo flag */
  1297.         /*       1 = mono */
  1298.         /*       2 = stereo */
  1299.         if (!ReadBufferedUnsignedChar(Input,&UnsignedChar))
  1300.             {
  1301.                 Error = eFileLoadDiskError;
  1302.              FailurePoint29:
  1303.                 goto FailurePoint28;
  1304.             }
  1305.         if (UnsignedChar == 2)
  1306.             {
  1307.                 NumChannels = eSampleStereo;
  1308.             }
  1309.         else if (UnsignedChar == 1)
  1310.             {
  1311.                 NumChannels = eSampleMono;
  1312.             }
  1313.         else
  1314.             {
  1315.                 Error = eFileLoadBadFormat;
  1316.              FailurePoint30:
  1317.                 goto FailurePoint29;
  1318.             }
  1319.  
  1320.         /*   1-byte number of bits per sample point */
  1321.         /*       should be 8 or 16 */
  1322.         if (!ReadBufferedUnsignedChar(Input,&UnsignedChar))
  1323.             {
  1324.                 Error = eFileLoadDiskError;
  1325.              FailurePoint31:
  1326.                 goto FailurePoint30;
  1327.             }
  1328.         if (UnsignedChar == 8)
  1329.             {
  1330.                 NumBits = eSample8bit;
  1331.             }
  1332.         else if (UnsignedChar == 16)
  1333.             {
  1334.                 NumBits = eSample16bit;
  1335.             }
  1336.         else
  1337.             {
  1338.                 Error = eFileLoadBadFormat;
  1339.              FailurePoint32:
  1340.                 goto FailurePoint31;
  1341.             }
  1342.  
  1343.         /*   n-bytes of data for sample frames */
  1344.         /*       stereo samples have the left channel sample point preceding the right */
  1345.         /*       channel sample point. */
  1346.         /*       sample points that require more than 1 byte are stored little endian */
  1347.         /*       all sample data is stored in signed 2's complement form */
  1348.         SampleObject->SampleData = NewSampleStorageActual(NumBits,NumChannels,
  1349.             NumSampleFrames);
  1350.         if (SampleObject->SampleData == NIL)
  1351.             {
  1352.                 Error = eFileLoadOutOfMemory;
  1353.              FailurePoint33:
  1354.                 goto FailurePoint32;
  1355.             }
  1356.         switch (NumBits)
  1357.             {
  1358.                 default:
  1359.                     EXECUTE(PRERR(ForceAbort,"SampleObjectNewFromFile:  bad NumBits value"));
  1360.                     break;
  1361.                 case eSample8bit:
  1362.                     switch (NumChannels)
  1363.                         {
  1364.                             default:
  1365.                                 EXECUTE(PRERR(ForceAbort,"SampleObjectNewFromFile:  bad NumChannels value"));
  1366.                                 break;
  1367.                             case eSampleMono:
  1368.                                 for (Scan = 0; Scan < NumSampleFrames; Scan += 1)
  1369.                                     {
  1370.                                         signed char                    SamplePoint;
  1371.  
  1372.                                         if (!ReadBufferedSignedChar(Input,&SamplePoint))
  1373.                                             {
  1374.                                              ErrorWhileReadingSampleData:
  1375.                                                 Error = eFileLoadDiskError;
  1376.                                                 DisposeSampleStorageActual(SampleObject->SampleData);
  1377.                                                 goto FailurePoint33;
  1378.                                             }
  1379.                                         SetSampleStorageActualValue(SampleObject->SampleData,Scan,
  1380.                                             eMonoChannel,double2largefixed((double)SamplePoint / MAX8BIT));
  1381.                                     }
  1382.                                 break;
  1383.                             case eSampleStereo:
  1384.                                 for (Scan = 0; Scan < NumSampleFrames; Scan += 1)
  1385.                                     {
  1386.                                         signed char                    SamplePoint;
  1387.  
  1388.                                         if (!ReadBufferedSignedChar(Input,&SamplePoint))
  1389.                                             {
  1390.                                                 goto ErrorWhileReadingSampleData;
  1391.                                             }
  1392.                                         SetSampleStorageActualValue(SampleObject->SampleData,Scan,
  1393.                                             eLeftChannel,double2largefixed((double)SamplePoint / MAX8BIT));
  1394.  
  1395.                                         if (!ReadBufferedSignedChar(Input,&SamplePoint))
  1396.                                             {
  1397.                                                 goto ErrorWhileReadingSampleData;
  1398.                                             }
  1399.                                         SetSampleStorageActualValue(SampleObject->SampleData,Scan,
  1400.                                             eRightChannel,double2largefixed((double)SamplePoint / MAX8BIT));
  1401.                                     }
  1402.                                 break;
  1403.                         }
  1404.                     break;
  1405.                 case eSample16bit:
  1406.                     switch (NumChannels)
  1407.                         {
  1408.                             default:
  1409.                                 EXECUTE(PRERR(ForceAbort,"SampleObjectNewFromFile:  bad NumChannels value"));
  1410.                                 break;
  1411.                             case eSampleMono:
  1412.                                 for (Scan = 0; Scan < NumSampleFrames; Scan += 1)
  1413.                                     {
  1414.                                         signed short                SamplePoint;
  1415.  
  1416.                                         if (!ReadBufferedSignedShortLittleEndian(Input,&SamplePoint))
  1417.                                             {
  1418.                                                 goto ErrorWhileReadingSampleData;
  1419.                                             }
  1420.                                         SetSampleStorageActualValue(SampleObject->SampleData,Scan,
  1421.                                             eMonoChannel,double2largefixed((double)SamplePoint / MAX16BIT));
  1422.                                     }
  1423.                                 break;
  1424.                             case eSampleStereo:
  1425.                                 for (Scan = 0; Scan < NumSampleFrames; Scan += 1)
  1426.                                     {
  1427.                                         signed short                SamplePoint;
  1428.  
  1429.                                         if (!ReadBufferedSignedShortLittleEndian(Input,&SamplePoint))
  1430.                                             {
  1431.                                                 goto ErrorWhileReadingSampleData;
  1432.                                             }
  1433.                                         SetSampleStorageActualValue(SampleObject->SampleData,Scan,
  1434.                                             eLeftChannel,double2largefixed((double)SamplePoint / MAX16BIT));
  1435.  
  1436.                                         if (!ReadBufferedSignedShortLittleEndian(Input,&SamplePoint))
  1437.                                             {
  1438.                                                 goto ErrorWhileReadingSampleData;
  1439.                                             }
  1440.                                         SetSampleStorageActualValue(SampleObject->SampleData,Scan,
  1441.                                             eRightChannel,double2largefixed((double)SamplePoint / MAX16BIT));
  1442.                                     }
  1443.                                 break;
  1444.                         }
  1445.                     break;
  1446.             }
  1447.  
  1448.         /* fill in other fields */
  1449.         SampleObject->DataModified = False;
  1450.         SampleObject->SampleWindow = NIL;
  1451.         SampleObject->CodeCenter = CodeCenter;
  1452.         SampleObject->MainWindow = MainWindow;
  1453.         SampleObject->SampleList = SampleList;
  1454.  
  1455.         *ObjectOut = SampleObject;
  1456.         return eFileLoadNoError;
  1457.     }
  1458.  
  1459.  
  1460. /* write the data in a sample object out to the file */
  1461. FileLoadingErrors            SampleObjectWriteOutData(SampleObjectRec* SampObj,
  1462.                                                 struct BufferedOutputRec* Output)
  1463.     {
  1464.         char*                                StringTemp;
  1465.         double                            NaturalFreqTemp;
  1466.         NumBitsType                    NumBits;
  1467.         NumChannelsType            NumChannels;
  1468.         long                                NumSampleFrames;
  1469.         long                                Scan;
  1470.         char*                                RawDataPointer;
  1471.  
  1472.         CheckPtrExistence(SampObj);
  1473.         CheckPtrExistence(Output);
  1474.  
  1475.         /*   1-byte sample version number */
  1476.         /*       should be 1 */
  1477.         if (!WriteBufferedUnsignedChar(Output,1))
  1478.             {
  1479.                 return eFileLoadDiskError;
  1480.             }
  1481.  
  1482.         /*   2-byte little endian window X position (signed, origin at top-left corner) */
  1483.         /* the way we're doing this, if the window is open when we save, the most */
  1484.         /* recent coordinates will not be saved. */
  1485.         if (!WriteBufferedSignedShortLittleEndian(Output,SampObj->SavedWindowXLoc))
  1486.             {
  1487.                 return eFileLoadDiskError;
  1488.             }
  1489.  
  1490.         /*   2-byte little endian window Y position */
  1491.         if (!WriteBufferedSignedShortLittleEndian(Output,SampObj->SavedWindowYLoc))
  1492.             {
  1493.                 return eFileLoadDiskError;
  1494.             }
  1495.  
  1496.         /*   2-byte little endian window width */
  1497.         if (!WriteBufferedSignedShortLittleEndian(Output,SampObj->SavedWindowWidth))
  1498.             {
  1499.                 return eFileLoadDiskError;
  1500.             }
  1501.  
  1502.         /*   2-byte little endian window height */
  1503.         if (!WriteBufferedSignedShortLittleEndian(Output,SampObj->SavedWindowHeight))
  1504.             {
  1505.                 return eFileLoadDiskError;
  1506.             }
  1507.  
  1508.         /*   4-byte little endian sample name length descriptor (positive 2's complement) */
  1509.         StringTemp = SampleObjectGetNameCopy(SampObj);
  1510.         if (StringTemp == NIL)
  1511.             {
  1512.                 return eFileLoadOutOfMemory;
  1513.             }
  1514.         if (!WriteBufferedSignedLongLittleEndian(Output,PtrSize(StringTemp)))
  1515.             {
  1516.                 ReleasePtr(StringTemp);
  1517.                 return eFileLoadDiskError;
  1518.             }
  1519.  
  1520.         /*   n-byte sample name text (line feed = 0x0a) */
  1521.         if (!WriteBufferedOutput(Output,PtrSize(StringTemp),StringTemp))
  1522.             {
  1523.                 ReleasePtr(StringTemp);
  1524.                 return eFileLoadDiskError;
  1525.             }
  1526.         ReleasePtr(StringTemp);
  1527.  
  1528.         /*   4-byte little endian sample formula length descriptor (positive 2's complement) */
  1529.         StringTemp = SampleObjectGetFormulaCopy(SampObj);
  1530.         if (StringTemp == NIL)
  1531.             {
  1532.                 return eFileLoadOutOfMemory;
  1533.             }
  1534.         if (!WriteBufferedSignedLongLittleEndian(Output,PtrSize(StringTemp)))
  1535.             {
  1536.                 ReleasePtr(StringTemp);
  1537.                 return eFileLoadDiskError;
  1538.             }
  1539.  
  1540.         /*   n-byte sample formula text (line feed = 0x0a) */
  1541.         if (!WriteBufferedOutput(Output,PtrSize(StringTemp),StringTemp))
  1542.             {
  1543.                 ReleasePtr(StringTemp);
  1544.                 return eFileLoadDiskError;
  1545.             }
  1546.         ReleasePtr(StringTemp);
  1547.  
  1548.         /*   4-byte little endian sample frame index of sample's origin */
  1549.         if (!WriteBufferedSignedLongLittleEndian(Output,SampleObjectGetOrigin(SampObj)))
  1550.             {
  1551.                 return eFileLoadDiskError;
  1552.             }
  1553.  
  1554.         /*   4-byte little endian sample frame index of loop 1 start */
  1555.         /*       must be a valid index, i.e. >= 0 and < num sample frames */
  1556.         if (!WriteBufferedSignedLongLittleEndian(Output,SampleObjectGetLoopStart1(SampObj)))
  1557.             {
  1558.                 return eFileLoadDiskError;
  1559.             }
  1560.  
  1561.         /*   4-byte little endian sample frame index of loop 1 end */
  1562.         /*       must be a valid index, i.e. >= 0 and < num sample frames */
  1563.         if (!WriteBufferedSignedLongLittleEndian(Output,SampleObjectGetLoopEnd1(SampObj)))
  1564.             {
  1565.                 return eFileLoadDiskError;
  1566.             }
  1567.  
  1568.         /*   4-byte little endian sample frame index of loop 2 start */
  1569.         /*       must be a valid index, i.e. >= 0 and < num sample frames */
  1570.         if (!WriteBufferedSignedLongLittleEndian(Output,SampleObjectGetLoopStart2(SampObj)))
  1571.             {
  1572.                 return eFileLoadDiskError;
  1573.             }
  1574.  
  1575.         /*   4-byte little endian sample frame index of loop 2 end */
  1576.         /*       must be a valid index, i.e. >= 0 and < num sample frames */
  1577.         if (!WriteBufferedSignedLongLittleEndian(Output,SampleObjectGetLoopEnd2(SampObj)))
  1578.             {
  1579.                 return eFileLoadDiskError;
  1580.             }
  1581.  
  1582.         /*   4-byte little endian sample frame index of loop 3 start */
  1583.         /*       must be a valid index, i.e. >= 0 and < num sample frames */
  1584.         if (!WriteBufferedSignedLongLittleEndian(Output,SampleObjectGetLoopStart3(SampObj)))
  1585.             {
  1586.                 return eFileLoadDiskError;
  1587.             }
  1588.  
  1589.         /*   4-byte little endian sample frame index of loop 3 end */
  1590.         /*       must be a valid index, i.e. >= 0 and < num sample frames */
  1591.         if (!WriteBufferedSignedLongLittleEndian(Output,SampleObjectGetLoopEnd3(SampObj)))
  1592.             {
  1593.                 return eFileLoadDiskError;
  1594.             }
  1595.  
  1596.         /*   4-byte little endian sampling rate value */
  1597.         if (!WriteBufferedSignedLongLittleEndian(Output,SampleObjectGetSamplingRate(SampObj)))
  1598.             {
  1599.                 return eFileLoadDiskError;
  1600.             }
  1601.  
  1602.         /*   4-byte little endian natural frequency fractional portion */
  1603.         /*       unsigned; divide by 2^32 to get the actual fraction */
  1604.         NaturalFreqTemp = SampleObjectGetNaturalFrequency(SampObj) + (1.0L / 8589934592.0L);
  1605.         if (!WriteBufferedUnsignedLongLittleEndian(Output,
  1606.             (unsigned long)((NaturalFreqTemp - (long)NaturalFreqTemp) * 4294967296.0L)))
  1607.             {
  1608.                 return eFileLoadDiskError;
  1609.             }
  1610.  
  1611.         /*   4-byte little endian natural frequency integer portion */
  1612.         if (!WriteBufferedSignedLongLittleEndian(Output,(long)NaturalFreqTemp))
  1613.             {
  1614.                 return eFileLoadDiskError;
  1615.             }
  1616.  
  1617.         /*   4-byte total number of sample frames */
  1618.         NumSampleFrames = SampleObjectGetNumSampleFrames(SampObj);
  1619.         if (!WriteBufferedSignedLongLittleEndian(Output,NumSampleFrames))
  1620.             {
  1621.                 return eFileLoadDiskError;
  1622.             }
  1623.  
  1624.         /*   1-byte mono/stereo flag */
  1625.         /*       1 = mono */
  1626.         /*       2 = stereo */
  1627.         NumChannels = SampleObjectGetNumChannels(SampObj);
  1628.         switch (NumChannels)
  1629.             {
  1630.                 default:
  1631.                     EXECUTE(PRERR(ForceAbort,"SampleObjectWriteOutData:  bad NumChannels"));
  1632.                     break;
  1633.                 case eSampleStereo:
  1634.                     if (!WriteBufferedUnsignedChar(Output,2))
  1635.                         {
  1636.                             return eFileLoadDiskError;
  1637.                         }
  1638.                     break;
  1639.                 case eSampleMono:
  1640.                     if (!WriteBufferedUnsignedChar(Output,1))
  1641.                         {
  1642.                             return eFileLoadDiskError;
  1643.                         }
  1644.                     break;
  1645.             }
  1646.  
  1647.         /*   1-byte number of bits per sample point */
  1648.         /*       should be 8 or 16 */
  1649.         NumBits = SampleObjectGetNumBits(SampObj);
  1650.         switch (NumBits)
  1651.             {
  1652.                 default:
  1653.                     EXECUTE(PRERR(ForceAbort,"SampleObjectWriteOutData:  bad NumBits"));
  1654.                     break;
  1655.                 case eSample8bit:
  1656.                     if (!WriteBufferedUnsignedChar(Output,8))
  1657.                         {
  1658.                             return eFileLoadDiskError;
  1659.                         }
  1660.                     break;
  1661.                 case eSample16bit:
  1662.                     if (!WriteBufferedUnsignedChar(Output,16))
  1663.                         {
  1664.                             return eFileLoadDiskError;
  1665.                         }
  1666.                     break;
  1667.             }
  1668.  
  1669.         /*   n-bytes of data for sample frames */
  1670.         /*       stereo samples have the left channel sample point preceding the right */
  1671.         /*       channel sample point. */
  1672.         /*       sample points that require more than 1 byte are stored little endian */
  1673.         /*       all sample data is stored in signed 2's complement form */
  1674.         RawDataPointer = SampleObjectGetRawData(SampObj);
  1675.         if (RawDataPointer == NIL)
  1676.             {
  1677.                 return eFileLoadOutOfMemory;
  1678.             }
  1679.         switch (NumChannels)
  1680.             {
  1681.                 default:
  1682.                     EXECUTE(PRERR(ForceAbort,"SampleObjectWriteOutData:  bad NumChannels"));
  1683.                     break;
  1684.                 case eSampleMono:
  1685.                     switch (NumBits)
  1686.                         {
  1687.                             default:
  1688.                                 EXECUTE(PRERR(ForceAbort,"SampleObjectWriteOutData:  bad NumBits"));
  1689.                                 break;
  1690.                             case eSample8bit:
  1691.                                 for (Scan = 0; Scan < NumSampleFrames; Scan += 1)
  1692.                                     {
  1693.                                         PRNGCHK(RawDataPointer,&(((signed char*)RawDataPointer)[Scan]),
  1694.                                             sizeof(((signed char*)RawDataPointer)[Scan]));
  1695.                                         if (!WriteBufferedSignedChar(Output,
  1696.                                             ((signed char*)RawDataPointer)[Scan]))
  1697.                                             {
  1698.                                                 return eFileLoadDiskError;
  1699.                                             }
  1700.                                     }
  1701.                                 break;
  1702.                             case eSample16bit:
  1703.                                 for (Scan = 0; Scan < NumSampleFrames; Scan += 1)
  1704.                                     {
  1705.                                         PRNGCHK(RawDataPointer,&(((signed short*)RawDataPointer)[Scan]),
  1706.                                             sizeof(((signed short*)RawDataPointer)[Scan]));
  1707.                                         if (!WriteBufferedSignedShortLittleEndian(Output,
  1708.                                             ((signed short*)RawDataPointer)[Scan]))
  1709.                                             {
  1710.                                                 return eFileLoadDiskError;
  1711.                                             }
  1712.                                     }
  1713.                                 break;
  1714.                         }
  1715.                     break;
  1716.                 case eSampleStereo:
  1717.                     switch (NumBits)
  1718.                         {
  1719.                             default:
  1720.                                 EXECUTE(PRERR(ForceAbort,"SampleObjectWriteOutData:  bad NumBits"));
  1721.                                 break;
  1722.                             case eSample8bit:
  1723.                                 for (Scan = 0; Scan < NumSampleFrames; Scan += 1)
  1724.                                     {
  1725.                                         PRNGCHK(RawDataPointer,
  1726.                                             &(((signed char*)RawDataPointer)[2 * Scan + 0]),
  1727.                                             sizeof(((signed char*)RawDataPointer)[2 * Scan + 0]));
  1728.                                         if (!WriteBufferedSignedChar(Output,
  1729.                                             ((signed char*)RawDataPointer)[2 * Scan + 0]))
  1730.                                             {
  1731.                                                 return eFileLoadDiskError;
  1732.                                             }
  1733.                                         PRNGCHK(RawDataPointer,
  1734.                                             &(((signed char*)RawDataPointer)[2 * Scan + 1]),
  1735.                                             sizeof(((signed char*)RawDataPointer)[2 * Scan + 1]));
  1736.                                         if (!WriteBufferedSignedChar(Output,
  1737.                                             ((signed char*)RawDataPointer)[2 * Scan + 1]))
  1738.                                             {
  1739.                                                 return eFileLoadDiskError;
  1740.                                             }
  1741.                                     }
  1742.                                 break;
  1743.                             case eSample16bit:
  1744.                                 for (Scan = 0; Scan < NumSampleFrames; Scan += 1)
  1745.                                     {
  1746.                                         PRNGCHK(RawDataPointer,
  1747.                                             &(((signed short*)RawDataPointer)[2 * Scan + 0]),
  1748.                                             sizeof(((signed short*)RawDataPointer)[2 * Scan + 0]));
  1749.                                         if (!WriteBufferedSignedShortLittleEndian(Output,
  1750.                                             ((signed short*)RawDataPointer)[2 * Scan + 0]))
  1751.                                             {
  1752.                                                 return eFileLoadDiskError;
  1753.                                             }
  1754.                                         PRNGCHK(RawDataPointer,
  1755.                                             &(((signed short*)RawDataPointer)[2 * Scan + 1]),
  1756.                                             sizeof(((signed short*)RawDataPointer)[2 * Scan + 1]));
  1757.                                         if (!WriteBufferedSignedShortLittleEndian(Output,
  1758.                                             ((signed short*)RawDataPointer)[2 * Scan + 1]))
  1759.                                             {
  1760.                                                 return eFileLoadDiskError;
  1761.                                             }
  1762.                                     }
  1763.                                 break;
  1764.                         }
  1765.                     break;
  1766.             }
  1767.  
  1768.         return eFileLoadNoError;
  1769.     }
  1770.  
  1771.  
  1772. /* mark sample object as not modified */
  1773. void                                    SampleObjectMarkAsSaved(SampleObjectRec* SampObj)
  1774.     {
  1775.         CheckPtrExistence(SampObj);
  1776.         if (SampObj->SampleWindow != NIL)
  1777.             {
  1778.                 SampleWindowWritebackModifiedData(SampObj->SampleWindow);
  1779.             }
  1780.         SampObj->DataModified = False;
  1781.     }
  1782.